/*
 * Date          Author      Note
 * 2014.11.24    wzwz        续片
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <mh/common.h>
#include "resource.h"
#include "func.h"
#include "lang.h"
#include "mhbtn.h"
#include "mhlabel.h"
#include "mhedit.h"
#include "extent.h"
#include "com.h"
#include "keypane.h"
#include "info.h"


#define EXTENT_CAPTION_LEFT       (CX_EDGE_LEFT)
#define EXTENT_CAPTION_TOP        (CY_TITLE4_HEIGHT)
#define EXTENT_CAPTION_WIDTH      (120)
#define EXTENT_CAPTION_HEIGHT     (28)
#define EXTENT_CAPTION_INTER      (CX_SINK_BMP / 3)
#define EXTENT_NAME_WIDTH         (42)

static void OnKeyDown(HWND hWnd, int key);
enum {CLOSE = 0, OPEN, ENABLE};
/*
 *
 */
static void CreateExtentInterface(HWND hWnd)
{
    int i, j;
    char sc[32] = {0};
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_SINK_BMP - CX_ASK_BMP * 2,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_FALSE]);
    CreateWindow (MH_LABEL_NAME,
        MW_EXTENT_CLOTH_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        EXTENT_CAPTION_LEFT,
        EXTENT_CAPTION_TOP,
        EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, MH_LABEL_COLOR_1GROUP);
    sprintf(sc, "%u", GetExtPieceNum(g_knit_data));
    CreateWindow (MH_EDIT_NAME,
        sc,
        WS_CHILD | BS_CENTER | WS_VISIBLE,
        IDC_EDIT_CLOTH,
        EXTENT_CAPTION_LEFT + EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_TOP,
        EXTENT_NAME_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, 0);
    //
    CreateWindow (MH_LABEL_NAME,
        MW_EXTENT_INTER_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        EXTENT_CAPTION_LEFT + EXTENT_CAPTION_INTER,
        EXTENT_CAPTION_TOP,
        EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, MH_LABEL_COLOR_1GROUP);
    sprintf(sc, "%u", GetExtPieceInter(g_knit_data));
    CreateWindow (MH_EDIT_NAME,
        sc,
        WS_CHILD | BS_CENTER | WS_VISIBLE,
        IDC_EDIT_INTER,
        EXTENT_CAPTION_LEFT + EXTENT_CAPTION_INTER + EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_TOP,
        EXTENT_NAME_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, 0);
    //
    CreateWindow (MH_LABEL_NAME,
        MW_EXTENT_WIDTH_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        EXTENT_CAPTION_LEFT + EXTENT_CAPTION_INTER * 2,
        EXTENT_CAPTION_TOP,
        EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, MH_LABEL_COLOR_1GROUP);
    sprintf(sc, "%u", GetExtPieceWidth(g_knit_data));
    CreateWindow (MH_EDIT_NAME,
        sc,
        WS_CHILD | BS_CENTER | WS_VISIBLE,
        IDC_EDIT_WIDTH,
        EXTENT_CAPTION_LEFT + EXTENT_CAPTION_INTER * 2 + EXTENT_CAPTION_WIDTH,
        EXTENT_CAPTION_TOP,
        EXTENT_NAME_WIDTH,
        EXTENT_CAPTION_HEIGHT,
        hWnd, 0);
    //
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    if(1)
    {
        char *str[10] = {
            "01",
            "02",
            "03",
            "04",
            "05",
            "06",
            "07",
            "08",
            "09",
            "10",
        };
        for(i = 0; i < 10; ++i)
        {
            CreateWindow (MH_LABEL_NAME,
                str[i],
                WS_CHILD | WS_VISIBLE,
                IDC_STATIC,
                EXTENT_CAPTION_LEFT,
                EXTENT_CAPTION_TOP + EXTENT_CAPTION_HEIGHT * (i + 1),
                EXTENT_NAME_WIDTH,
                EXTENT_CAPTION_HEIGHT,
                hWnd, MH_LABEL_COLOR_1GROUP);
            //
            int open = GetExtPieceEnable(g_knit_data, i);
            CreateWindow (MH_EDIT_NAME,
                open ? MW_OPEN_CAPTION : MW_CLOSE_CAPTION,
                WS_CHILD | WS_VISIBLE,
                ID_BUTTON1 + i,
                EXTENT_CAPTION_LEFT + EXTENT_NAME_WIDTH,
                EXTENT_CAPTION_TOP + EXTENT_CAPTION_HEIGHT * (i + 1),
                EXTENT_NAME_WIDTH,
                EXTENT_CAPTION_HEIGHT,
                hWnd, 0);
            for(j = 0; j < data.pextent->yarn_num; ++j)
            {
                sprintf(sc, "%u", data.pextent->ext_yarn[i][j]);
                CreateWindow (MH_EDIT_NAME,
                    sc,
                    WS_CHILD | BS_CENTER | WS_VISIBLE,
                    IDC_EDIT1 + i * 16 + j,
                    EXTENT_CAPTION_LEFT + EXTENT_NAME_WIDTH * (j + 2),
                    EXTENT_CAPTION_TOP + EXTENT_CAPTION_HEIGHT * (i + 1),
                    EXTENT_NAME_WIDTH,
                    EXTENT_CAPTION_HEIGHT,
                    hWnd, 0);
            }
        }
    }
}
/*
 *
 */
static int CheckData(HWND hWnd)
{
    int ret = 0;
    int piece = GetExtPieceNum(g_knit_data);
    if(piece < 1)
    {
        return -1;
    }
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    int i = 0, j = 0;
    int count = 0;
    ushort yarn_used = 0;
    for(i = 0; i < 10; ++i)
    {
        if(GetExtPieceEnable(g_knit_data, i) && data.pextent)
        {
            for(j = 0; j < data.pextent->yarn_num; ++j)
            {
                uchar yarn = data.pextent->ext_yarn[i][j];
                if((yarn >= 1 && yarn <= 8) || (yarn >= 11 && yarn <= 18))
                {
                    if(yarn >= 1 && yarn <= 8)
                    {
                        --yarn;
                    }
                    else
                    {
                        yarn -= 3;
                    }
                    if(yarn_used & (1 << yarn))
                    {
                        return -2;
                    }
                    else
                    {
                        yarn_used |= 1 << yarn;
                    }
                }
                else
                {
                    return -2;
                }
            }
            ++count;
        }
    }
    if(count != piece)
    {
        return -1;
    }
    return ret;
}
/*
 *展开篇幅的值更新
 */
static void UpdateExtPiece(HWND hWnd)
{
    ushort inter = GetExtPieceInter(g_knit_data);
    ushort width = GetFlowerWidth(g_knit_data);
    int i = 0;
    for(i = 1; i < 10; ++i)
    {
        if(GetExtPieceEnable(g_knit_data, i))
        {
            width += (width + inter) * i;
        }
    }
    SetExtPieceWidth(g_knit_data, width);
    char str[32] = { 0 };
    sprintf(str, "%u", width);
    HWND hTmp = GetDlgItem(hWnd, IDC_EDIT_WIDTH);
    SetWindowCaption(hTmp, str);
    InvalidateRect(hTmp, NULL, TRUE);
}
/*
 *  设置变化后的片数， 针数，还有沙嘴
 */
static void OnSetKnitValue(HWND hWnd, int nID)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    const char *sc = GetWindowCaption(GetDlgItem(hWnd, nID));
    if(nID == IDC_EDIT_CLOTH)
    {
        uchar n = atoi(sc);
        SetExtPieceNum(g_knit_data, n);
        UpdateExtPiece(hWnd);
    }
    else if(nID == IDC_EDIT_INTER)
    {
        ushort n = atoi(sc);
        SetExtPieceInter(g_knit_data, n);
        UpdateExtPiece(hWnd);
    }
    else if(nID >= IDC_EDIT1 + 16 && nID < IDC_EDIT1 + 160)
    {
        uchar n = atoi(sc);
        uchar dat = 0;
        int i = (nID - IDC_EDIT1) / 16;
        int j = (nID - IDC_EDIT1) & 0x0F;
        data.pextent->ext_yarn[i][j] = n;
        dat = data.pextent->ext_yarn[i][j];
        if(dat <= 8)
        {
            SetExtPieceYarn(g_knit_data, i, j, dat);
        }
        else
        {
            SetExtPieceYarn(g_knit_data, i, j, dat - 2);
        }
    }
    data.pextent->change = TRUE;
}
/*
 *
 */
static void OnExtEnable(HWND hWnd, ushort nID, uchar code)
{
    int index = nID - ID_BUTTON1;
    int enable = GetExtPieceEnable(g_knit_data, index);
    enable = !enable;
    SetExtPieceEnable(g_knit_data, index, enable);
    const char *sc = MW_CLOSE_CAPTION;
    switch (code)
    {
    case CLOSE:
            sc = MW_CLOSE_CAPTION;
        break;
    case OPEN:
        sc = MW_OPEN_CAPTION;
        break;
    case ENABLE:
        sc = enable ? MW_OPEN_CAPTION : MW_CLOSE_CAPTION;
        break;
    }
    HWND hTmp = GetDlgItem(hWnd, nID);
    SetWindowCaption(hTmp, sc);
    InvalidateRect(hTmp, NULL, TRUE);

    UpdateExtPiece(hWnd);

    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    data.pextent->change = TRUE;
}
/*
 *
 */
static void OnBtnCmd(HWND hWnd, int nID)
{
    if(nID == ID_ESC)
    {
       OnKeyDown(hWnd, SCANCODE_ESCAPE);
    }
    else if(nID >= IDC_EDIT1 + 16 && nID < IDC_EDIT1 + 160)
    {
        HWND hTmp = GetDlgItem(hWnd, nID);
        RECT rect;
        GetClientRect(hTmp, &rect);
        ClientToScreen(hTmp, &rect.left, &rect.top);
        ClientToScreen(hTmp, &rect.right, &rect.bottom);
        CreateKeyboardWindow(hWnd, rect, 0, 18, atoi(GetWindowCaption(hTmp)));
    }
    else if(nID == IDC_EDIT_CLOTH || nID == IDC_EDIT_INTER)
    {
        HWND hTmp = GetDlgItem(hWnd, nID);
        RECT rect;
        GetClientRect(hTmp, &rect);
        ClientToScreen(hTmp, &rect.left, &rect.top);
        ClientToScreen(hTmp, &rect.right, &rect.bottom);
        int min = 0;
        int max = 10;
        if(nID == IDC_EDIT_INTER)
        {
            min = 1;
            max = GetTotalNeedle(g_knit_data);
        }
        CreateKeyboardWindow(hWnd, rect, min, max, atoi(GetWindowCaption(hTmp)));
    }
    else if(nID >= ID_BUTTON1 && nID < ID_BUTTON1 + 10)
    {
        OnExtEnable(hWnd, nID, ENABLE);
    }
}
/*
 *
 */
static void OnKeyDown(HWND hWnd, int key)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    if(key == SCANCODE_ESCAPE)
    {
        int valid = TRUE;
        if(data.pextent->change)
        {
            if(CheckData(hWnd))
            {
                AfxInfoBox(hWnd, NULL, GetString(697));
                valid = FALSE;
            }
            else
            {
                if(WriteMacFile(MAC_PARAM_FILE, g_knit_data))
                {
                    AfxInfoBox(hWnd, NULL, GetString(481));
                }
                else
                {
                    MH_FILE_SYNC();
                }
                SendWorkParam(g_knit_data);
                SendExtentPieceData(g_knit_data);
            }
        }
        if(valid)
        {
            PostMessage(hWnd, MSG_CLOSE, 0, 0);
        }
    }
    else if(key == SCANCODE_ENTER)
    {
        ushort nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID >= ID_BUTTON1 && nID < ID_BUTTON1 + 10)
        {
            OnExtEnable(hWnd, nID, ENABLE);
        }
        else
        {
            OnBtnCmd(hWnd, nID);
        }
    }
    else if(key == SCANCODE_F1)
    {
        SetExtPieceEnable(g_knit_data, 0, 0);
        ushort nID = GetDlgCtrlID(GetFocusChild(hWnd));
        OnExtEnable(hWnd, nID, CLOSE);
    }
    else if(key == SCANCODE_F2)
    {
        SetExtPieceEnable(g_knit_data, 0, 1);
        ushort nID = GetDlgCtrlID(GetFocusChild(hWnd));
        OnExtEnable(hWnd, nID, OPEN);
    }
    else if(key == SCANCODE_F3)
    {
        SetFocusChild(GetDlgItem(hWnd, IDC_EDIT_CLOTH));
    }
    else if(key == SCANCODE_F4)
    {
        SetFocusChild(GetDlgItem(hWnd, IDC_EDIT_INTER));
    }
    else if(key == SCANCODE_CURSORBLOCKRIGHT)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID == IDC_EDIT_CLOTH)
        {
            nID = IDC_EDIT_INTER;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_INTER)
        {
            nID = IDC_EDIT_WIDTH;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_WIDTH)
        {
            //
        }
        else if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + 160)
        {
            if(((nID - IDC_EDIT1) & 0x0F) < data.pextent->yarn_num - 1)
            {
                ++nID;
                SetFocusChild(GetDlgItem(hWnd, nID));
            }
        }
    }
    else if(key == SCANCODE_CURSORBLOCKLEFT)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID == IDC_EDIT_CLOTH)
        {
            //
        }
        else if(nID == IDC_EDIT_INTER)
        {
            nID = IDC_EDIT_CLOTH;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_WIDTH)
        {
            nID = IDC_EDIT_INTER;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + 160)
        {
            if((nID - IDC_EDIT1) & 0x0F)
            {
                --nID;
                SetFocusChild(GetDlgItem(hWnd, nID));
            }
        }
    }
    else if(key == SCANCODE_CURSORBLOCKUP)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID >= IDC_EDIT1 + 16 && nID < IDC_EDIT1 + 160)
        {
            nID -= 16;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + 5)
        {
            nID = IDC_EDIT_CLOTH;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID >= IDC_EDIT1 + 5 && nID < IDC_EDIT1 + 11)
        {
            nID = IDC_EDIT_INTER;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID >= IDC_EDIT1 + 11 && nID < IDC_EDIT1 + 16)
        {
            nID = IDC_EDIT_WIDTH;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
    else if(key == SCANCODE_CURSORBLOCKDOWN)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + 144)
        {
            nID += 16;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_CLOTH)
        {
            nID = IDC_EDIT1 + 1;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_INTER)
        {
            nID = IDC_EDIT1 + 7;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID == IDC_EDIT_WIDTH)
        {
            nID = IDC_EDIT1 + 14;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
}
/*
 *
 */
static int ExtentWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MSG_CREATE:
        {
            CreateExtentInterface(hWnd);
        }
        break;
    case MSG_PAINT:
        {
            HDC hdc = GetClientDC(hWnd);
            RECT rect;
            GetClientRect(hWnd, &rect);
            rect.left += 30;
            rect.top += MASTER_TITLE_TOP;
            rect.right -= 30;
            rect.bottom = rect.top + MASTER_TITLE_HEIGHT - 1;
            SetBkMode(hdc, BM_TRANSPARENT);
            SetTextColor(hdc, COLOR_HQ_CYAN(hdc));
            DrawText(hdc, GetWindowCaption (hWnd), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            ReleaseDC(hdc);
        }
        break;
    case MSG_CLOSE:
        {
            HWND hHosting = GetHosting(hWnd);
            if(hHosting > 0)
            {
                EnableWindow(hHosting, TRUE);
            }
            DestroyMainWindow(hWnd);
            MainWindowCleanup(hWnd);
        }
        return 0;
    case MSG_DESTROY:
        {
            ShowWindow(hWnd, SW_HIDE);
            DestroyAllControls(hWnd);
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            if(data.pextent)
            {
                free(data.pextent);
                SetWindowAdditionalData(hWnd, 0);
            }
        }
        break;
    case MSG_KEYDOWN:
        {
            OnKeyDown(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_ERASEBKGND:
        {
            DrawBitmapBkGnd(hWnd, (RECT*)lParam, &g_bmp[BMP_SINK]);
        }
        return 0;
    case MSG_COMMAND:
        {
            OnBtnCmd(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_SETDATA:
        {
            OnSetKnitValue(hWnd, LOWORD(wParam));
        }
        return 0;
    }
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/*
 *
 */
HWND CreateExtentWindow(HWND hHosting)
{
    int x = (CX_SCREEN - CX_SINK_BMP) / 2;
    int y = (CY_SCREEN - CY_SINK_BMP) / 2;

    WND_EXTRA_DATA data;
    data.pextent = calloc(1, sizeof(WND_EXTENT));
    uchar yarn_used[16] = {0};
    data.pextent->yarn_num = GetSourceYarnDrt(g_knit_data, yarn_used, 1);
    GetExchangedYarnDrt(g_knit_data, yarn_used);
    int i = 0, j = 0, k = 0;
    uchar dat;
    for(i = 0; i < 16; ++i)
    {
        if(yarn_used[i])
        {
            if(j < data.pextent->yarn_num)
            {
                data.pextent->ext_yarn[0][j] = i < 8 ? i + 1 : i + 2;
                dat = data.pextent->ext_yarn[0][j];
                if(dat <= 8)
                {
                     SetExtPieceYarn(g_knit_data, 0, j, dat);
                }
                else
                {
                    SetExtPieceYarn(g_knit_data, 0, j, dat  - 2);
                }
                for(k = 0; k < 10; k++)
                {
                    dat = GetExtPieceYarn(g_knit_data, k, j);
                    if(dat <= 8)
                    {
                        data.pextent->ext_yarn[k][j] = dat;
                    }
                    else
                    {
                        data.pextent->ext_yarn[k][j] = dat + 2;
                    }
                }
            }
            else
            {
                printf("conflict extent data\n");
            }
            ++j;
        }
    }

    MAINWINCREATE CreateInfo;
    CreateInfo.dwStyle = WS_VISIBLE;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = MW_EXTENT_SET_CAPTION;
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = ExtentWinProc;
    CreateInfo.lx = x;
    CreateInfo.ty = y;
    CreateInfo.rx = x + CX_SINK_BMP;
    CreateInfo.by = y + CY_SINK_BMP;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = data.value;
    CreateInfo.hHosting = hHosting;
    HWND hWnd = CreateMainWindow(&CreateInfo);
    if(hWnd != HWND_INVALID)
    {
        SwitchToKnitState(g_knit_data, FALSE);
        EnableWindow(hHosting, FALSE);
        SetFocusChild(GetDlgItem(hWnd, ID_BUTTON1));
        ShowWindow(hWnd, SW_SHOWNORMAL);
    }
    return hWnd;
}
